
// helloworldDlg.cpp : implementation file
//

#include "stdafx.h"
#include "helloworld.h"
#include "helloworldDlg.h"
#include "afxdialogex.h"


#include "../../../sdk/inc/SDS_Device_Api.h"
#pragma comment(lib, "../../../sdk/lib/win32/SDS_Device_Sdk.lib")

//#include "./decode/decode.h"
#pragma comment(lib, "./decode/ST_Decode.lib")
#pragma warning(disable:4996)


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


SDS_Device::sdk::_handle g_hStream = NULL;


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// Dialog Data
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CHelloWorldDlg dialog



CHelloWorldDlg::CHelloWorldDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_HELLOWORLD_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CHelloWorldDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_INFO, m_ctrlInfo);
}

BEGIN_MESSAGE_MAP(CHelloWorldDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_START2, &CHelloWorldDlg::OnBnClickedButtonStart)
	ON_BN_CLICKED(IDC_BUTTON_STOP2, &CHelloWorldDlg::OnBnClickedButtonStop)
	ON_BN_CLICKED(IDC_BUTTON_OPENSTREAM, &CHelloWorldDlg::OnBnClickedButtonOpenstream)
	ON_BN_CLICKED(IDC_BUTTON_CLOSESTREAM, &CHelloWorldDlg::OnBnClickedButtonClosestream)
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CHelloWorldDlg message handlers

BOOL CHelloWorldDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	g_hStream = NULL;

	//
	m_pDecode = CreateDecode();
	m_pDecode->Init(NULL);
	m_nDec = -1;

	m_ctrlInfo.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
	m_ctrlInfo.InsertColumn(0, _T("info"), LVCFMT_LEFT, 1000);


	SetDlgItemText(IDC_EDIT_SERVERIP, _T("192.168.1.100"));
	SetDlgItemText(IDC_EDIT_SERVER_PORT, _T("7706"));
	SetDlgItemText(IDC_EDIT_DEVICEID, _T("10000"));
	SetDlgItemText(IDC_EDIT_CHANNEL, _T("1"));


	SetTimer(1, 1000, NULL);
	return TRUE;  // return TRUE  unless you set the focus to a control
}


void CHelloWorldDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: Add your message handler code here and/or call default
	std::vector<std::string>		vtInfoTemp;
	{
		std::unique_lock<std::mutex> lock(m_mutex);
		vtInfoTemp = m_vtInfo;
	}

	m_ctrlInfo.DeleteAllItems();

	for (int i = 0; i < (int)vtInfoTemp.size(); i++)
	{
		m_ctrlInfo.InsertItem(m_ctrlInfo.GetItemCount(), (TCHAR*)_bstr_t(vtInfoTemp[i].c_str()));
	}

	CDialogEx::OnTimer(nIDEvent);
}


void CHelloWorldDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CHelloWorldDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

int CALLBACK OnEventCB(long long llUserData, const char* strEvent, int nEventType)
{
	CHelloWorldDlg *pDlg = (CHelloWorldDlg *)(AfxGetApp()->m_pMainWnd);

	TRACE("time %d   %s \r\n", ::GetTickCount(), strEvent);

	pDlg->addInfo(strEvent);
	return 0;
}


int CALLBACK OnFrameCB(SDS_Device::sdk::_handle stream, BYTE* lpBuf, int size, long long llStamp, int type, int channel, long long llUserData)
{
	TRACE(_T("recv frame  type %x   size  %d    time  %lld    channel  %d   tick %d ---\r\n"), type, size, llStamp, channel, ::GetTickCount());
	//CHelloWorldDlg *pDlg = (CHelloWorldDlg *)(AfxGetApp()->m_pMainWnd);
	CHelloWorldDlg *pDlg = (CHelloWorldDlg *)llUserData;

	if (type == 0x68643030)//em_FrameType_Header_Frame		= 0x68643030,	//头帧('00dh')
	{
		pDlg->m_pDecode->InputDecodeStream(pDlg->m_nDec, 1, (BYTE*)lpBuf, size, llStamp);
		pDlg->m_pDecode->CtrlPlay(pDlg->m_nDec, 3, 1);
	}
	else if (type == 0x69643030)//"00di"
	{
		sds::device::pst_file_info p = (sds::device::pst_file_info)lpBuf; //当开始时间戳（微秒） + 时长（毫秒）<= 当前时间戳 ，即可结束
		if (p->uiVideoCodec == 0)//TTX_VIDEO_CODEC_H264
			pDlg->m_pDecode->InputDecodeStream(pDlg->m_nDec, 2, (BYTE*)lpBuf, size, llStamp);
		else
			pDlg->m_pDecode->InputDecodeStream(pDlg->m_nDec, 3, (BYTE*)lpBuf, size, llStamp);
	}
	else
	{
		pDlg->m_pDecode->InputDecodeStream(pDlg->m_nDec, type, (BYTE*)lpBuf, size, llStamp);
	}

	return 0;
}


// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CHelloWorldDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CHelloWorldDlg::OnBnClickedButtonStart()
{
	// TODO: Add your control notification handler code here
		// TODO: 在此添加控件通知处理程序代码
	char     szServerIp[32] = { 0 };
	char     szServerPort[32] = { 0 };
	::GetDlgItemTextA(this->GetSafeHwnd(), IDC_EDIT_SERVERIP, szServerIp, 32);
	::GetDlgItemTextA(this->GetSafeHwnd(), IDC_EDIT_SERVER_PORT, szServerPort, 32);

	szServerPort[sizeof(szServerPort) - 1] = 0;
	int nPort = atoi(szServerPort);

	SDS_Device::sdk::st_work_param param;
	memset(&param, 0, sizeof(param));
	strcpy(param.server, szServerIp);
	param.port = nPort;
	param.callbackEvent = OnEventCB;
	param.callbackFrame = OnFrameCB;
	param.llUserData = (long long)this;
	SDS_Device::sdk::SDS_NetDevice_Init(param);

	addInfo("server start!  ");
}


void CHelloWorldDlg::addInfo(const char* strEvent)
{
	std::unique_lock<std::mutex> lock(m_mutex);

	m_vtInfo.push_back(strEvent);

	if (m_vtInfo.size() > 20)
	{
		m_vtInfo.erase(m_vtInfo.begin());
	}

}

void CHelloWorldDlg::OnBnClickedButtonStop()
{
	// TODO: Add your control notification handler code here
	SDS_Device::sdk::SDS_NetDevice_Uninit();

	addInfo("server stop!  ");

}


void CHelloWorldDlg::OnBnClickedButtonOpenstream()
{
	// TODO: Add your control notification handler code here

	char     szDeviceId[32] = { 0 };
	::GetDlgItemTextA(this->GetSafeHwnd(), IDC_EDIT_DEVICEID, szDeviceId, 32);

	char	szChan[32] = { 0 };
	::GetDlgItemTextA(this->GetSafeHwnd(), IDC_EDIT_CHANNEL, szChan, 32);

	int nChan = atoi(szChan);

	//视频
	//video
	SDS_Device::sdk::SDS_NetDevice_OpenStream(szDeviceId, nChan, sds::device::eStreamType::eMainStream, g_hStream);

	//音频
	//audio
	//SDS_Device::sdk::SDS_NetDevice_OpenStream(szDeviceId, 1, SDS_Device::enums::eStreamType::eAudioStream, stream);
	m_nDec = m_pDecode->OpenDecodeChan(GetDlgItem(IDC_STATIC_VIDEO)->GetSafeHwnd(), 0);
	m_pDecode->CtrlPlay(m_nDec, 3, 1);
}


void CHelloWorldDlg::OnBnClickedButtonClosestream()
{
	// TODO: 在此添加控件通知处理程序代码
	if (g_hStream)
	{
		SDS_Device::sdk::SDS_NetDevice_CloseStream(g_hStream);
		g_hStream = NULL;
	}

	if (m_nDec != -1)
	{
		m_pDecode->CtrlPlay(m_nDec, 3, 0);
		m_pDecode->CloseDecodeChan(m_nDec);
		m_nDec = -1;
	}

}
